#!/usr/bin/env python

# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Street Identity Demo Identity Provider."""

import fix_path #@UnresolvedImport @UnusedImport

from google.appengine.dist import use_library
use_library('django', '1.2')

import os

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template

import cgi
import logging

from lib import authn
from lib import utils

import model
import account
import dbinit
import app_params as _idp_params

from lib.loggable import loggable

from lib import oauth2server
from lib import openid
from lib import streetaddress
from lib import attribute

__author__ = "Maciej Machulak"
__maintainer__ = "Maciej Machulak"
__email__ = "mmachulak@google.com"

__copyright__ = "Copyright 2011, Google Inc."
__license__ = "Apache License 2.0"
__version__ = "0.1"
__status__ = "Prototype"

class MainHandler(webapp.RequestHandler):

    @authn.redirect_logged_user(_idp_params.Config.SUCCESS_LOGIN_REDIRECT)
    @loggable('main page')
    def get(self, *args):
        continue_to = self.request.get(_idp_params.Http.CONTINUE_TO)
        if continue_to is None:
          values = {}
        else:
          values = {
           _idp_params.Template.CONTINUE_TO : continue_to
          }
        path = os.path.join(os.path.dirname(__file__), 'templates/index.html')
        self.response.out.write(template.render(path, values))

class SignInHandler(webapp.RequestHandler):

    @loggable('sign in')
    def post(self):
        
        username = cgi.escape(self.request.get(_idp_params.Template.USERNAME))
        password = cgi.escape(self.request.get(_idp_params.Template.PASSWORD))
        continue_to = self.request.get(_idp_params.Http.CONTINUE_TO)
        user = model.User.all().filter('username = ', username).filter('password = ', password).get()
        if user:
          logging.debug('found the user')
          session = model.Session(id = utils.random(), user=user)
          session.put()          
          self.response.headers.add_header('set-cookie', _idp_params.Http.SESSION_ID +  '=' + str(session.id))
          logging.debug('session has been stored and set')
          if continue_to is None or len(continue_to) == 0:
            logging.debug('no continue url - redirecting to %s' % _idp_params.Config.SUCCESS_LOGIN_REDIRECT)
            self.redirect(_idp_params.Config.SUCCESS_LOGIN_REDIRECT)
            return
          else:
            logging.debug('redirecting to %s' % continue_to)
            self.redirect(continue_to)
            return
        logging.error('could not authenticate the user - not found')
        self.redirect('/')
      
class SignOutHandler(webapp.RequestHandler):
    
    @authn.login_required
    @loggable('sign out')
    def get(self):
        session = self.session
        session.delete()
        logging.debug('session deleted')
        self.response.headers.add_header('set-cookie', _idp_params.Http.SESSION_ID + '=')
        continue_to = self.request.get(_idp_params.Http.CONTINUE_TO)
        if continue_to and len(continue_to) > 0:
          self.redirect(continue_to)
          return
        self.redirect('/')   
        
class SignUpHandler(webapp.RequestHandler):
  
    @loggable('sign up')
    def get(self):
        error = self.request.get('error')
        if error is not None and len(error) > 0:
          values = {
            'error': True
            }
        else:
          values = {}
        path = os.path.join(os.path.dirname(__file__), 'templates/sign_up.html')
        self.response.out.write(template.render(path, values))  

    @loggable('sign up')
    def post(self):
        display_name = cgi.escape(self.request.get(_idp_params.Template.DISPLAY_NAME))
        email = cgi.escape(self.request.get(_idp_params.Template.EMAIL))
        username = cgi.escape(self.request.get(_idp_params.Template.USERNAME))        
        password = cgi.escape(self.request.get(_idp_params.Template.PASSWORD))
        user = model.User.all().filter('username = ', username).get()
        if user:
          logging.error('user already exists')
          self.redirect('/sign_up?error=user_exists')
          return      
        user = model.User(username = username,
                password = password,
                email = email,
                display_name = display_name)
        user.put()
        logging.debug('user \' %s \'put under key: %s' % (user.username,user.key())) 
        session = model.Session(id = utils.random(), user=user)
        session.put()
        logging.debug('session stored within the database')
        self.response.headers.add_header('set-cookie', _idp_params.Http.SESSION_ID + '=' + str(session.id))
        self.redirect('/')         
      
application = webapp.WSGIApplication([('/', MainHandler),
                                      ('/sign_in', SignInHandler),
                                      ('/sign_out', SignOutHandler),
                                      ('/sign_up', SignUpHandler),
                                      
                                      ('/account', account.AccountHandler),
                                      ('/account/delete', account.DelAuthorizationHandler),
                                                                            
                                      ('/oauth/authorize', oauth2server.AuthorizationHandler),
                                      ('/oauth/token', oauth2server.TokenHandler),
                                      
                                      ('/oauth/user_info', openid.UserInfoHandler), 

                                      ('/street_address/(.*)', streetaddress.StreetAddressHandler),
                                      ('/street_address_token/(.*)', attribute.AttributeTokenHandler),
                                      
                                      ('/db_setup', dbinit.DBSetupHandler)],
                                     debug=True)

def main():
    logging.getLogger().setLevel(logging.DEBUG)  
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
